package event

import (
	"sync"

	"github.com/mars/pkg/loggers"
)

type ApplicationEvent[T any] struct {
	once  sync.Once
	name  string
	event chan T
}

func NewApplicationEvent[T any](name string) *ApplicationEvent[T] {
	return &ApplicationEvent[T]{
		name:  name,
		event: make(chan T),
	}
}

func NewApplicationEventWithCap[T any](name string, cap int) *ApplicationEvent[T] {
	return &ApplicationEvent[T]{
		name:  name,
		event: make(chan T, cap),
	}
}

func (event *ApplicationEvent[T]) Name() string {
	return event.name
}

func (event *ApplicationEvent[T]) Publish(info T) {
	event.event <- info
}

func (event *ApplicationEvent[T]) Event() chan T {
	return event.event
}

func (event *ApplicationEvent[T]) Consumer(consumer func(info T)) {
	for e := range event.event {
		consumer(e)
	}
	loggers.Info("all events are processed successfully")
}

// Close 关闭事件处理器，这个事件处理器可以被多次关闭，但是最终只会执行一次
func (event *ApplicationEvent[T]) Close() {
	event.once.Do(func() {
		close(event.event)
		loggers.Info("applicationEvent %s is closed", event.name)
	})
}
